package com.xjm.ips.service;

import com.xjm.ips.entity.Department;
import com.xjm.ips.entity.Employeeec;
import com.xjm.ips.entity.MyPage;
import com.xjm.ips.mapper.DepartmentMapper;
import com.xjm.ips.mapper.EmployeeecMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collector;
import java.util.stream.Collectors;

@Service
public class ViewService {
    @Autowired
    DepartmentMapper departmentMapper;
    @Autowired
    EmployeeecMapper employeeecMapper;
    @Autowired
    RedisService redisService;

    private List<Department> departmentList = null;


    public List<Department> getEveryDeparmentNumbers(){
        return departmentMapper.getEveryDeparmentNumbers();
    }

    /**
     * 人员请假和迟到统计
     * @param pageNo
     * @param pageSize
     * @return
     */
    public MyPage getEmpLateandTakeLeave(Integer pageNo, Integer pageSize) {
        if(pageNo!=null && pageSize!=null){
            pageNo = (pageNo-1)*pageSize;
        }
        List<Employeeec> data = employeeecMapper.getEmpLateandTakeLeave(pageNo,pageSize);
        Long total = employeeecMapper.getTotalFromView();
        MyPage myPage = new MyPage();
        myPage.setData(data);
        myPage.setTotal(total);
        return myPage;
    }

    /**
     * 获取各部门人员个数（可能存在个别部门没有人数统计)
     * 再从部门里获取一个树形结构
     * 根据各部门人数的检索路径在树里面做计算
     * 最后把树转化成列表list
     * 再用steam将List进行排序
     * @return
     */
    @Transactional
    public List<Department> getDeparmentNumbers(){
        List<Department> allDepartmentsById = departmentMapper.getAllDepartmentsById(-1);
        List<Department> everyDeparmentNumbers = departmentMapper.getEveryDeparmentNumbers();
        for (Department everyDeparmentNumber : everyDeparmentNumbers) {
            List<String> depPath = Arrays.stream(everyDeparmentNumber.getDepPath().split("\\."))
                    .collect(Collectors.toList());
            departmentCount(allDepartmentsById,depPath,everyDeparmentNumber.getCount());
        }
        List<Department> deparmentNumbers = new ArrayList<>();
        castDepartmentTreetoList(deparmentNumbers, allDepartmentsById);
        deparmentNumbers = deparmentNumbers.stream().sorted(Comparator.comparing(Department::getCount).reversed()).collect(Collectors.toList());
        return deparmentNumbers;
    }


    public void departmentCount(List<Department> departmentList,List<String> depPath,Integer count){
        if(depPath.size()==1){
            return;
        }
        for (Department department : departmentList) {
            if(depPath.indexOf(department.getId().toString())==-1){
                continue;
            }
            department.setCount(department.getCount()+count);
            depPath.remove(department.getId().toString());
            departmentCount(department.getChildren(),depPath,count);
        }
    }


    public void castDepartmentTreetoList(List<Department> resultList,List<Department> oldList){
        for (Department department : oldList) {
            if(department.getChildren().size()==0){
                resultList.add(addDepartment(department));
                continue;
            }
            resultList.add(addDepartment(department));
            castDepartmentTreetoList(resultList,department.getChildren());
        }
    }


    public Department addDepartment(Department department){
        Department resultDepartment = new Department();
        resultDepartment.setId(department.getId());
        resultDepartment.setName(department.getName());
        resultDepartment.setCount(department.getCount());
        return resultDepartment;
    }


    @Transactional
    public List<Department> getDepartmentRewardOrPenalty(){
        List<Department> allDepartmentsById = departmentMapper.getAllDepartmentsById(-1);
        List<Department> departmentRps = departmentMapper.getDepartmentRps();
        for (Department departmentRp : departmentRps) {
            List<String> depPath = Arrays.stream(departmentRp.getDepPath().split("\\."))
                    .collect(Collectors.toList());
            DepartmentRewardOrPenalty(allDepartmentsById,depPath,departmentRp.getLate(),departmentRp.getTakeLeave());
        }
        List<Department> DepartmentRewardOrPenalties = new ArrayList<>();
        castDepartmentRewardOrPenaltyTreetoList(DepartmentRewardOrPenalties, allDepartmentsById);
        DepartmentRewardOrPenalties = DepartmentRewardOrPenalties.stream().sorted(Comparator.comparing(Department::getLate).
                thenComparing(Department::getTakeLeave).reversed()).collect(Collectors.toList());
        return DepartmentRewardOrPenalties;
    }


    public void DepartmentRewardOrPenalty(List<Department> departmentList,List<String> depPath,Integer late,Integer takeLeave){
        if(late==0&&takeLeave==0){
            return;
        }
        if(depPath.size()==1){
            return;
        }
        for (Department department : departmentList) {
            if(depPath.indexOf(department.getId().toString())==-1){
                continue;
            }
            department.setLate(department.getLate()+late);
            department.setTakeLeave(department.getTakeLeave()+takeLeave);
            depPath.remove(department.getId().toString());
            DepartmentRewardOrPenalty(department.getChildren(),depPath,late,takeLeave);
        }
    }


    public Department addDepartmentRewardOrPenalty(Department department){
        Department resultDepartment = new Department();
        resultDepartment.setId(department.getId());
        resultDepartment.setName(department.getName());
        resultDepartment.setLate(department.getLate());
        resultDepartment.setTakeLeave(department.getTakeLeave());
        return resultDepartment;
    }

    public void castDepartmentRewardOrPenaltyTreetoList(List<Department> resultList,List<Department> oldList){
        for (Department department : oldList) {
            if(department.getChildren().size()==0){
                resultList.add(addDepartmentRewardOrPenalty(department));
                continue;
            }
            resultList.add(addDepartmentRewardOrPenalty(department));
            castDepartmentRewardOrPenaltyTreetoList(resultList,department.getChildren());
        }
    }

    public void initDeparmentNumbersOfRedis(){
        departmentList = getDeparmentNumbers();
        redisService.set("departmentNumbers",departmentList);
    }
}
